
#include "MCU_TimeManager.h"


void TimeManagerCreate(TimeManager* base)
{
    uint8_t i = 0;
    uint8_t length = 0;

    if (base != NULL)
    {
        length = sizeof(base->TimeRegObjHandle) / sizeof(base->TimeRegObjHandle[0]);
        for (i = 0; i < length; i++)
        {
            base->TimeRegObjCountMs[i] = 0; //客房时间调整
            base->TimeRegObjCountMsTemp[i] = 0; //客房时间调整
            base->TimeRegObjHandle[i].TimeReg = 0; //客房打扫
            base->TimeRegObjHandle[i].funcdoCount = 0; //客房打扫
            base->TimeRegObjHandle[i].LoopCan = 0; //客房打扫
            base->TimeRegObjHandle[i].funptr = 0; //客人不再入住
        }
    }
}

static unsigned char TimeManagerAdd(TimeManager *base, TimeRegObj *obj)
{ //增加一个会员
    unsigned char i = 0;
    unsigned char length = 0;

    if ((base != 0) && (0 != obj))
    {
        length = sizeof(base->TimeRegObjHandle) / sizeof(base->TimeRegObjHandle[0]);
        for (i = 0; i < length; i++)
        {
            if (base->TimeRegObjHandle[i].funptr == obj->funptr)
            { //该会员已经注册过了
                // printf("TimerObj Registered!!!\n");
                return 'r'; //r是已经注册好了
            }
            if (0 == base->TimeRegObjHandle[i].funptr)
            {
                base->TimeRegObjHandle[i].funptr = obj->funptr;
                base->TimeRegObjHandle[i].LoopCan = obj->LoopCan;
                base->TimeRegObjHandle[i].TimeReg = obj->TimeReg;
                base->TimeRegObjCountMs[i] = obj->TimeReg;
                return 'k';
            }
        }
        printf("bad !!! in time\n");
        return 'n';
    }
    return 'n';
}

void TimeManagerScanTimeMs(TimeManager *base, int freq_ms)
{ //由中断触发执行
    unsigned char i = 0;
    unsigned char length = 0;

    if (base != NULL)
    {
        length = sizeof(base->TimeRegObjHandle) / sizeof(base->TimeRegObjHandle[0]);
        for (i = 0; i < length; i++)
        {
            if ((base->TimeRegObjHandle[i].funptr) != NULL) //continue; //管理会员区域没有被注册过
            {
                if (base->TimeRegObjCountMs[i] > 0) base->TimeRegObjCountMs[i] -= freq_ms;
                if ((base->TimeRegObjCountMs[i] == 0) || (base->TimeRegObjCountMs[i] < 0))
                {
                    base->TimeRegObjHandle[i].Trigger = 1;
                    base->TimeRegObjCountMs[i] = base->TimeRegObjHandle[i].TimeReg; //自动重装载值，从会员类的值里得到数据
                }
            }
        }
    }
}

void TimeManagerScan(TimeManager *base)
{
    unsigned char i = 0;
    unsigned char length = 0;

    if (base == NULL) return;
    length = sizeof(base->TimeRegObjHandle) / sizeof(base->TimeRegObjHandle[0]);
    for (i = 0; i < length; i++)
    {
        if ((base->TimeRegObjHandle[i].funptr) != NULL)
        {
            if (base->TimeRegObjHandle[i].Trigger == 0) continue;
            base->TimeRegObjHandle[i].Trigger = 0;
            if ('k' == base->TimeRegObjHandle[i].LoopCan)
            {
                ((TimeRegHandleFptr)(base->TimeRegObjHandle[i].funptr))(); //执行函数
            }
            else if ('n' == base->TimeRegObjHandle[i].LoopCan)
            {
                if (base->TimeRegObjHandle[i].funcdoCount == 0) continue; //会员执行次数为0
                if ((TimeRegHandleFptr *)(base->TimeRegObjHandle[i].funptr) != 0)
                { //会员的执行函数存在
                    ((TimeRegHandleFptr)(base->TimeRegObjHandle[i].funptr))();
                    base->TimeRegObjHandle[i].funcdoCount--;
                    base->TimeRegObjCountMs[i] = base->TimeRegObjHandle[i].TimeReg;
                }
                if ((base->TimeRegObjHandle[i].funcdoCount) == 0)
                {
                    TimeManagerDelete(base, (TimeRegObj *)&(base->TimeRegObjHandle[i])); //属于多次性的会员
                }
            }
        }
    }
}

TimeRegObj *TimeManagerCheck(TimeManager *base, TimeRegObj *obj)
{ //检测一个会员是不是注册过，否则返回0
    unsigned char i = 0;
    unsigned char length = 0;

    if ((base != 0) && (0 != obj))
    {
        length = sizeof(base->TimeRegObjHandle) / sizeof(base->TimeRegObjHandle[0]);
        for (i = 0; i < length; i++)
        {
            if (base->TimeRegObjHandle[i].funptr == obj->funptr)
            {                                         //该会员已经注册过了
                return &base->TimeRegObjHandle[i]; //r是已经注册好了
            }
        }
        return 0;
    }
    return 0;
}

unsigned char TimeManagerCheckTimeIsOver(TimeManager *base, TimeRegObj *obj)
{
    unsigned char i = 0;
    unsigned char length = 0;

    if (base == 0) return 'n';
    if (obj == 0) return 'n';
    length = sizeof(base->TimeRegObjHandle) / sizeof(base->TimeRegObjHandle[0]);
    if (0 != TimeManagerCheck(base, obj))
    { //该会员已经注册过了
        for (i = 0; i < length; i++)
        {
            if (base->TimeRegObjHandle[i].funptr == obj->funptr)
            { //该会员已经注册过了
                if ('k' == base->TimeRegObjHandle[i].LoopCan)
                { //永久会员
                    if (base->TimeRegObjCountMs[i] > 0)
                    {
                        return 'n';
                    }
                    else
                    {
                        return 'k';
                    }
                }
                else if ('n' == base->TimeRegObjHandle[i].LoopCan)
                {
                    if (0 == base->TimeRegObjHandle[i].funcdoCount) return 'n'; //会员执行次数为0
                    return 'k';
                }
            }
        }
    }
    return 'n';
}

void TimeManagerDelete(TimeManager *base, TimeRegObj *obj)
{ //从管理员的会员列表中删除删除一个会员
    unsigned char i = 0;
    unsigned char length = 0;

    if (base == NULL) return;
    if (obj == NULL) return;
    length = sizeof(base->TimeRegObjHandle) / sizeof(base->TimeRegObjHandle[0]);
    for (i = 0; i < length; i++)
    {
        if (&base->TimeRegObjHandle[i] == obj)
        { //该会员已经注册过了
            base->TimeRegObjHandle[i].funptr = 0;
            base->TimeRegObjHandle[i].LoopCan = 0;
            base->TimeRegObjCountMs[i] = 0;
            base->TimeRegObjCountMsTemp[i] = 0;
        }
    }
}

void TimeManagerDelAll(TimeManager *base)
{
    unsigned char i = 0;
    unsigned char length = 0;

    if (base == NULL) return;
    length = sizeof(base->TimeRegObjHandle) / sizeof(base->TimeRegObjHandle[0]);
    for (i = 0; i < length; i++)
    {
        if (base->TimeRegObjHandle[i].funptr != NULL)
        { //该会员已经注册过了
            TimeRegObjDestory(base, &base->TimeRegObjHandle[i]);
            base->TimeRegObjHandle[i].funptr = NULL;
            base->TimeRegObjCountMs[i] = 0;
        }
    }
}
void TimeManagerUpdataTime(TimeManager *base, TimeRegObj *obj, int time)
{
    unsigned char i = 0;
    unsigned char length = 0;

    if (base == NULL) return;
    if (obj == NULL) return;
    length = sizeof(base->TimeRegObjHandle) / sizeof(base->TimeRegObjHandle[0]);
    for (i = 0; i < length; i++)
    {
        if (&base->TimeRegObjHandle[i] == obj)
        {                                               //该会员已经注册过了
            base->TimeRegObjCountMs[i] = time; //客房时间调整
            base->TimeRegObjCountMsTemp[i] = 0;   //客房时间调整
        }
    }
}

TimeRegObj* TimeRegObjCreate(void (*Handle)(), int time, TimeManager *Manager)
{ //Manager是会员的管理员
    TimeRegObj obj;
    TimeRegObj* ret_obj;
    unsigned char res = 0;

    obj.funptr = (TimeRegHandleFptr)Handle;
    obj.TimeReg = time;
    obj.LoopCan = 'k';
    if ((0 == Handle) || (0 == Manager)) return 0;
    res = TimeManagerAdd(Manager, &obj);
    if (('r' == res) || ('k' == res))
    { //添加成功，会员注册过,或者注册成功
        ret_obj = TimeManagerCheck(Manager, &obj);
        return ret_obj;
    }
    else
    {
        //添加失败
        // while(1){;}
        return NULL;
    }
}

void TimeRegObjDestory(TimeManager* base, TimeRegObj* obj)
{
    if (obj != NULL)
    {
        if (base == NULL) return;
        TimeManagerDelete(base, obj); //记账本清理
        obj = NULL;
    }
}

void TimeRegObjUpdataTime(TimeManager *Manager, TimeRegObj *obj, int time)
{
    if (obj == NULL) return;
    if (Manager == NULL) return;

    obj->TimeReg = time;
    TimeManagerUpdataTime(Manager, obj, time);
}
void TimeManager_RunCount(TimeRegObj *obj, int count)
{
    if (obj == NULL) return;

    obj->funcdoCount = count;
    obj->LoopCan = 'n';
}
